﻿// --------------------------------
// <copyright file="Level.cs" company="Faculty of Information Technology, Czech Technical University in Prague">
//     This document is shared by Microsoft Public License (MS-PL)
//     For further details please see http://msdn.microsoft.com/en-us/library/ff648068.aspx or license.txt.
// </copyright>
// <author>Lukáš Molnár, Vladislav Richter</author>

// <email>molnaluk@fit.cvut.cz</email>

// <date>7. 12. 2011 21:04:25</date>

// <summary>
//
// </summary>
// --------------------------------

using System.Collections.Generic;
using FITClub.Episode1.Components;
using FITClub.Episode1.Components.Particles.ParticleSystems;
using Microsoft.Xna.Framework;

namespace FITClub.Episode1.Levels
{
    public class Level : DrawableGameComponent
    {
        private bool loadPhysics;

        

        #region Public properties

        public LevelConfig Config { get; set; }

        public Background BackgroundModel { get; private set; }

        public List<BackgroundItem> BackgroundItems { get; set; }

        public List<PowerUp> PowerupItems { get; set; }

        public List<PlatformTile> PlatformModels { get; set; }

        public FluidDeath Fluid { get; set; }

        #endregion Public properties

        public Level(GameFITClub game, LevelConfig levelConfig, bool loadPhysics)
            : base(game)
        {
            this.Config = levelConfig;
            this.PlatformModels = new List<PlatformTile>(32);
            this.BackgroundItems = new List<BackgroundItem>();
            this.loadPhysics = loadPhysics;
        }

        public override void Initialize()
        {
            base.Initialize();
            BackgroundModel = new Background(Game as GameFITClub, this);
            Game.Components.Add(BackgroundModel);
#if !WINDOWS_PHONE
            for (int i = 0; i < this.Config.Particles.Count; i++)
            {
                if (this.Config.Particles[i].DrawOrder == DrawPosition.BeforeFluid)
                {
                    ParticleEffect pe = new ParticleEffect(this.Game, this.Config.Particles[i].Position, this.Config.Particles[i].Deserialize());
                    Game.Components.Add(pe);
                }
            }
#endif

            this.Fluid = new FluidDeath(Game as GameFITClub, this.Config.Fluid);
            this.Game.Components.Add(Fluid);

#if !WINDOWS_PHONE
            for (int i = 0; i < this.Config.Particles.Count; i++)
            {
                if (this.Config.Particles[i].DrawOrder == DrawPosition.BeforeBackgroundItems)
                {
                    ParticleEffect pe = new ParticleEffect(this.Game, this.Config.Particles[i].Position, this.Config.Particles[i].Deserialize());
                    Game.Components.Add(pe);
                }
            }
#endif
            Config.BackgroundItems.ForEach((BackgroundItemConfig bic) =>
            {
                var bi = new BackgroundItem(Game as GameFITClub, bic);
                this.BackgroundItems.Add(bi);
                this.Game.Components.Add(bi);
            });

#if !WINDOWS_PHONE
            for (int i = 0; i < this.Config.Particles.Count; i++)
            {
                if (this.Config.Particles[i].DrawOrder == DrawPosition.BeforePlatforms)
                {
                    ParticleEffect pe = new ParticleEffect(this.Game, this.Config.Particles[i].Position, this.Config.Particles[i].Deserialize());
                    Game.Components.Add(pe);
                }
            }
#endif
            ReloadPlatforms();
            bool netGame = false;
            try
            {
                netGame = (this.Game as GameFITClub).NewtworkGame;
            }
            catch { }
            if (netGame == false)
            {
                ReloadPowerups();
            }
        }

        public void ReloadPowerups()
        {
            if (this.PowerupItems != null)
            {
                this.PowerupItems.ForEach((PowerUp pt) =>
                {
                    this.Game.Components.Remove(pt);
                    pt.Dispose();
                });
                this.PowerupItems.Clear();
            }
            else
            {
                this.PowerupItems = new List<PowerUp>(4);
            }
            int pindex = 0;
            foreach (var item in Config.PowerUpConfigs)
            {
                PowerUp pu = new PowerUp(Game as GameFITClub, item, loadPhysics, pindex++);
                this.PowerupItems.Add(pu);
                this.Game.Components.Add(pu);
            }
        }

        /// <summary>
        /// Action called in Level Builder
        /// </summary>
        public void ReloadPlatforms()
        {
            if (this.PlatformModels != null)
            {
                this.PlatformModels.ForEach((PlatformTile pt) =>
                {
                    this.Game.Components.Remove(pt);
                    pt.Dispose();
                });
                this.PlatformModels.Clear();
            }
            else
            {
                this.PlatformModels = new List<PlatformTile>(32);
            }

            foreach (var item in Config.Platforms)
            {
                PlatformTile pt = new PlatformTile(Game as GameFITClub, item, loadPhysics);
                this.PlatformModels.Add(pt);
                this.Game.Components.Add(pt);
            }
        }

        public void ReloadConfig()
        {
            this.PlatformModels.ForEach((PlatformTile pt) => pt.ReloadConfig());
            this.BackgroundItems.ForEach((BackgroundItem bi) => bi.ReloadConfig());
            this.PowerupItems.ForEach((PowerUp pu) => pu.ReloadConfig());
            this.Fluid.ReloadConfig();
        }

        public void UpdateWorld()
        {
            this.PlatformModels.ForEach((PlatformTile pt) => pt.UpdateWorld());
            this.BackgroundItems.ForEach((BackgroundItem bi) => bi.UpdateWorld());
            this.PowerupItems.ForEach((PowerUp pu) => pu.UpdateWorld());
            this.Fluid.UpdateWorld();
        }

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
            this.Game.Components.Remove(BackgroundModel);
            this.Game.Components.Remove(Fluid);
            this.PlatformModels.ForEach((PlatformTile pt) =>
            {
                this.Game.Components.Remove(pt);
                pt.Dispose();
            });
            this.BackgroundItems.ForEach((BackgroundItem bi) =>
            {
                this.Game.Components.Remove(bi);
                bi.Dispose();
            });
            bool netGame = false;
            try{
                netGame = (this.Game as GameFITClub).NewtworkGame;
            }catch{}
            if (netGame == false)
            {
                this.PowerupItems.ForEach((PowerUp pu) =>
                {
                    this.Game.Components.Remove(pu);
                    pu.Dispose();
                });
            }
        }

        public new void Dispose()
        {
            this.Dispose(true);
        }
    }
}